#pragma once

#include <QObject>
#include <qthread.h>
#include <qstring.h>
#include <string>
#include <open62541.h>
#include <qmutex.h>
#include "common.h"


class ClientThread  : public QThread
{
	Q_OBJECT

public:

	ClientThread(QObject *parent = NULL);
	~ClientThread();
	static ClientThread* getInstance();
	static void deleteInstance();

	void connect();
	void disconnect();

	int server_port = 4840;
	std::string endpoint = "opc.tcp://localhost";
	UA_Client* client = NULL;
	UA_ClientConfig* client_config = NULL;
	char connect_statue = 0;
	bool threadRuning = true;
	
	std::string client_log = "client_log.txt";
	enum BaseTypeNumeric
	{
		BOOLVALUE=1,
		FLOATVALUE=10
	};

	void emit_update_node(OPC_NODE_ID node) { emit update_node(node); }

	void emit_update_numeric_node(int namespaceIndex, int numeric) { emit update_numeric_node(namespaceIndex, numeric); }
	void emit_update_string_node(int namespaceIndex, QString qstring) { emit update_string_node(namespaceIndex, qstring); }
	void write_log(char* line, bool recover = false);
private:
	
	QMutex log_write_mutex;

	void browserNodes();
	void threadStop();
	void clearMonitorItems();
	UA_StatusCode addMonitorItems();
	
	static ClientThread* ptr_instance;
	UA_NodeId* node_array = nullptr;
	int node_array_lenght = 0;
	UA_UInt32 subId;
	UA_UInt32* monItemsId = nullptr;
	UA_MonitoredItemCreateRequest* monRequests = nullptr;
	UA_Client_DataChangeNotificationCallback* callbacks = nullptr;
	UA_Client_DeleteMonitoredItemCallback* deleteCallbacks = nullptr;
	UA_NodeId** contexts = nullptr;
private slots:
	void slot_connect();
	void slot_disconnect();
signals:
	void connect_close();

	void update_node(OPC_NODE_ID node);
	void update_numeric_node(int namespaceIndex, int numeric);
	void update_string_node(int namespaceIndex, QString qstring);
protected:
	void run();
	
	
};
